<script setup lang="ts">
import {useSystemStore} from '~/store/system'
import request from '@/utils/request'
import {SUCCESS_CODE} from '~/common/constants'
import {throwError} from '~/utils/throwError'

import {Viewer} from '@bytemd/vue-next'
import gfm from '@bytemd/plugin-gfm'
import highlight from '@bytemd/plugin-highlight-ssr'
import {rehype} from 'rehype'

const plugins = [
  gfm(),
  highlight()
]

const route = useRoute()
const systemStore = useSystemStore()
const articleInfo = ref({})

try {
  const res = await request(`/article?id=${route.params.id}`, {
    method: 'GET',
    server: true,
    key: `article${route.params.id}`
  })
  const { code, msg, data} = res.data.value
  if (code !== SUCCESS_CODE) {
    throwError(msg)
  } else {
    /**
     * title
     * content
     * source
     * publishDate
     * tags
     */
    articleInfo.value = data
    useHead({
      title: `${articleInfo.value.title} - ${systemStore.siteInfo['site-name']}`
    })
  }
} catch (e) {
  throwError(e.message)
}

const viewerRef = ref()
const catalog = ref([])

onMounted(() => {
  const html = viewerRef.value.$el.innerHTML
  //// 为文章生成目录菜单
  // 1.通过rehype转换为AST
  const processor = rehype()
  const ast = processor.parse(html)
  // 2.为h2标签添加data-id属性
  addHeadingDataId(ast)
  // 3.将处理后的HTML内容赋值回Viewer
  viewerRef.value.$el.innerHTML = processor.stringify(ast)
})

function addHeadingDataId(ast) {
  let headingCount = 0;
  visit(ast, 'element', (node) => {
    if (node.tagName === 'h2') {
      if (node.children.length) {
        catalog.value.push(node.children[0].value)
      }
      node.properties['data-id'] = `heading-${headingCount++}`
    }
  })
}
function visit(node, type, fn) {
  if (!node) return;
  if (type === 'element' && node.type === 'element') {
    fn(node)
  }
  const children = 'children' in node ? node.children : node.value
  if (Array.isArray(children)) {
    children.forEach((child) => visit(child, type, fn))
  } else if (children && typeof children === 'object') {
    visit(children, type, fn)
  }
}
</script>

<template>
  <main :class="['container', 'main-container',{top: systemStore.topViewNav}]">
    <div class="view column-view">
      <!-- 主内容区 Start-->
      <div class="main-area article-area">
        <article class="article">
          <h1 class="article-title">
            {{articleInfo.title}}
          </h1>
          <div class="author-info-block">
            <div class="author-info-box">
              <div class="author-name">
                <p class="username">
                  <span class="name">{{articleInfo.author}}</span>
                </p>
              </div>
              <div class="meta-box">
                <time datetime="2023-03-07T05:49:42.000Z" title="Tue Mar 07 2023 14:49:42 GMT+0900 (Japan Standard Time)" class="time">
                  {{ articleInfo.publishTime }}
                </time>
              </div>
            </div>
          </div>
          <div class="article-content markdown-viewer">
            <Viewer ref="viewerRef" class="markdown-body"
                    :value="articleInfo.content"
                    :plugins="plugins"
            />
          </div>
        </article>
        <!-- 渲染标签 Start -->
        <div class="article-end" v-if="articleInfo.tagList && articleInfo.tagList.length">
          <div class="tag-list-box">
            <div class="tag-list">
              <div class="tag-list-title">标签:</div>
              <div class="tag-list-container">
                <p class="item tag-item" v-for="(item, index) in articleInfo.tagList" :key="index">
                  <span class="tag-title">{{item.name}}</span>
                </p>
              </div>
            </div>
          </div>
        </div>
        <!-- 渲染标签 End -->
        <!-- 评论区 Start -->
        <CommentBox :id="route.params.id" :type="0"/>
        <!-- 评论区 End -->
      </div>
      <!-- 主内容区 End-->

      <!-- 其他咨询推荐 Start -->
      <div class="main-area recommended-area entry-list-container shadow">
        <div class="recommended-list-title-wrapper">
          <div class="title">
            <span class="title-content">相关文章</span>
          </div>
        </div>
      </div>
      <!-- 其他咨询推荐 End -->

      <!-- 工具栏 Start -->
      <SuspendedPanel/>
      <!-- 工具栏 End -->
    </div>
  </main>
</template>

<style scoped lang="scss">
.main-container {
  max-width: 1140px;
  & > .view {
    margin-top: 21px;
  }
  .column-view {
    padding:0 0 96px;
  }
}

.article-area {
  margin-bottom: 20px;
}
.main-area {
  position: relative;
  max-width: 100%;
  @include clearfix;
  & > .article,& > .article-end {
    border-radius: 4px;
    background-color: var(--tidy-layer-1);
    padding-left: 32px;
    padding-right: 32px;
    box-sizing: border-box;
  }
  .article {
    position: relative;
    padding-top: 32px;
    padding-bottom: 20px;
    z-index: 1;
    overflow: hidden;
    .article-title {
      margin: 0 0 20px;
      font-size: 26px;
      font-weight: 600;
      line-height: 1.31;
      color: var(--tidy-font-1);
    }
    .author-info-block {
      display: flex;
      align-items: center;
      margin-bottom: 20px;
      .author-info-box {
        display: flex;
        min-width: 0;
        flex-grow: 1;
        .author-name {
          height: 24px;
          display: flex;
          align-items: center;
          .username {
            font-size: 14px;
            font-weight: 500;
            color: var(--tidy-font-2);
            line-height: 24px;
            @include text-overflow;
            .name {
              max-width:256px;
              display: inline-block;
              vertical-align: top;
              @include text-overflow;
            }
          }
        }
        .meta-box {
          font-size: 14px;
          color: var(--tidy-font-3);
          line-height: 22px;
          display: flex;
          align-items: center;
          .time {
            letter-spacing: 1px;
            margin-left: 16px;
          }
          .read-icon {
            margin-left: 16px;
            margin-right: 5px;
          }
        }
      }
    }
  }
  .article-end {
    padding-top: 10px;
    border-radius: 0 0 4px 4px;
    padding-bottom: 32px;
  }
  .recommended-list-title-wrapper {
    border-radius: 4px;
    background-color: var(--tidy-layer-1);
    padding-left: 32px;
    padding-right: 32px;
    .title {
      border-bottom: 1px solid var(--tidy-gray-1-1);
      box-sizing: border-box;
      width: 100%;
      .title-content {
        display: inline-block;
        font-size: 18px;
        font-weight: 600;
        color: var(--tidy-font-1);
        line-height: 30px;
        padding: 16px 0 12px;
      }
    }
  }
}

.markdown-body {
  word-break: break-word;
  line-height: 1.75;
  font-weight: 400;
  font-size: 16px;
  padding-bottom:10px;
  color: #252933;
  overflow:hidden;
}

.tag-list-box {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  margin-bottom: -12px;
  .tag-list {
    display: flex;
    font-size: 14px;
    line-height: 2.286;
    .tag-list-title {
      flex-shrink: 0;
      margin-right: 8px;
      font-size: 14px;
      height: 43px;
      color: var(--tidy-font-2);
    }
    .tag-list-container {
      display: flex;
      flex-wrap: wrap;
    }
    .tag-title {
      white-space: nowrap;
      line-height: 32px;
    }
    .item {
      display: flex;
      align-items: center;
      margin: 0 12px 12px 0;
      padding: 0 12px;
      border-radius: 4px;
      transition: background-color .15s linear;
      &.tag-item {
        background-color: var(--tidy-gray-3);
        color: var(--tidy-font-2);
      }
    }
  }
}
</style>
